package encaps.logging;

import encaps.utils.DatabaseUtil;
import java.sql.*;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import javax.ejb.*;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class Log implements EntityBean {

    public static final String LOGIN = "LOGIN";
    public static final String LOGOUT = "LOGOUT";
    public static final String REGISTRATION = "REGISTRATION";
    public static final String INSERT = "CREATE";
    public static final String UPDATE = "EDIT";
    public static final String DELETE = "REMOVE";
    private Long id;
    private String action;
    private Long user_id;
    private String user_name;
    private Timestamp time;
    private String entity_type;
    private Long entity_id;
    private String entity_name;
    private EntityContext context;
    private DataSource dataSource;

    public void setEntityContext(EntityContext aContext) {
        context = aContext;
        try {
            dataSource = DatabaseUtil.getDataSource();
        } catch (NamingException e) {
            throw new EJBException("DataSource lookup error", e);
        }
    }

    public void ejbActivate() {
    }

    public void ejbPassivate() {
    }

    public void ejbRemove() throws RemoveException {
        PreparedStatement ps = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            ps = conn.prepareStatement("DELETE FROM log WHERE id=?");
            ps.setLong(1, id);
            if (ps.executeUpdate() < 1) {
                throw new RemoveException("Deletion error. Id=" + id);
            }
        } catch (SQLException ex) {
            throw new EJBException("Error in Log.ejbRemove method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, ps);
        }
    }

    public Long ejbCreate(String action, Long user_id, String user_name, Date time,
            String entity_type, Long entity_id, String entity_name) throws CreateException {
        PreparedStatement insertValuesQuery = null;
        PreparedStatement selectIdQuery = null;
        Connection conn = null;
        try {
            this.action = action;
            this.user_id = user_id;
            this.user_name = user_name;
            this.time = new Timestamp(time.getTime());
            this.entity_type = entity_type;
            if (entity_id == -1) {
                this.entity_id = null;
            } else {
                this.entity_id = entity_id;
            }
            this.entity_name = entity_name;

            conn = dataSource.getConnection();
            insertValuesQuery = conn.prepareStatement("INSERT INTO log(action, user_id, user_name, time, entity_type, entity_id, entity_name) VALUES(?, ?, ?, ?, ?, ?, ?)");
            insertValuesQuery.setString(1, this.action);
            insertValuesQuery.setLong(2, this.user_id);
            insertValuesQuery.setString(3, this.user_name);



            insertValuesQuery.setTimestamp(4, this.time);
            insertValuesQuery.setString(5, this.entity_type);

            if (this.entity_id == null) {
                insertValuesQuery.setString(6, null);
            } else {
                insertValuesQuery.setLong(6, this.entity_id);
            }

            insertValuesQuery.setString(7, this.entity_name);
            if (insertValuesQuery.executeUpdate() != 1) {
                throw new CreateException("Insert error");
            }
            selectIdQuery = conn.prepareStatement("SELECT LAST_INSERT_ID()");
            ResultSet rs = selectIdQuery.executeQuery();
            if (!rs.next()) {
                throw new CreateException("Insert error");
            }
            this.id = rs.getLong(1);
            return this.id;
        } catch (Exception ex) {
            throw new EJBException("Error in Log.ejbCreate method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, selectIdQuery);
            DatabaseUtil.closeConnection(null, insertValuesQuery);
        }
    }

    public void ejbPostCreate(String action, Long user_id, String user_name, Date time,
            String entity_type, Long entity_id, String entity_name) {
    }

    public void unsetEntityContext() {
        context = null;
    }

    public void ejbLoad() {
        id = (Long) context.getPrimaryKey();
        PreparedStatement ps = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            ps = conn.prepareStatement("SELECT * FROM log WHERE id=?");
            ps.setLong(1, id);
            ResultSet rs = ps.executeQuery();
            if (!rs.next()) {
                throw new NoSuchEntityException("No log found by id = " + id);
            }
            action = rs.getString(Logger.ACTION);
            user_id = rs.getLong(Logger.USER_ID);
            user_name = rs.getString(Logger.USER_NAME);
            time = rs.getTimestamp(Logger.TIME);
            entity_type = rs.getString(Logger.ENTITY_TYPE);
            entity_id = rs.getLong(Logger.ENTITY_ID);
            entity_name = rs.getString(Logger.ENTITY_NAME);
        } catch (SQLException ex) {
            throw new EJBException("Error in Log.ejbLoad method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, ps);
        }
    }

    public void ejbStore() {
    }

    public java.lang.Long ejbFindByPrimaryKey(java.lang.Long aKey) throws FinderException {
        PreparedStatement ps = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            ps = conn.prepareStatement("SELECT id FROM log WHERE id=?;");
            ps.setLong(1, aKey);
            ResultSet rs = ps.executeQuery();
            if (!rs.next()) {
                throw new ObjectNotFoundException("No log found by primary key = " + aKey);
            }
            return aKey;
        } catch (SQLException ex) {
            throw new EJBException("Error in Log.ejbFindByPrimaryKey method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, ps);
        }
    }

    public Collection ejbFindAllAuthReg() {
        PreparedStatement ps = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            ps = conn.prepareStatement("SELECT id FROM log WHERE action=? OR action=?;");
            ps.setString(1, LOGIN);
            ps.setString(2, REGISTRATION);
            Collection logs = new LinkedList();
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                logs.add(rs.getLong(1));
            }
            return logs;
        } catch (SQLException ex) {
            throw new EJBException("Error in Log.ejbFindAllAuthReg method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, ps);
        }
    }

    public Collection ejbFindAllInUpDel() {
        PreparedStatement ps = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            ps = conn.prepareStatement("SELECT id FROM log WHERE action=? OR action=? OR action=?;");
            ps.setString(1, INSERT);
            ps.setString(2, UPDATE);
            ps.setString(3, DELETE);
            Collection logs = new LinkedList();
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                logs.add(rs.getLong(1));
            }
            return logs;
        } catch (SQLException ex) {
            throw new EJBException("Error in Log.ejbFindAllAuthReg method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, ps);
        }
    }

    public Collection ejbFindPaged(Integer from, Integer count) {
        PreparedStatement ps = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            ps = conn.prepareStatement("SELECT id FROM log LIMIT ?, ?");
            ps.setInt(1, from);
            ps.setInt(2, count);
            Collection logs = new LinkedList();
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                logs.add(rs.getLong(1));
            }
            return logs;
        } catch (SQLException ex) {
            throw new EJBException("Error in Log.ejbFindAllAuthReg method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, ps);
        }
    }

    public Collection ejbFindBeetweenPaged(Integer from, Integer count, Date after, Date before) {
        PreparedStatement ps = null;
        Connection conn = null;
        try {
            Timestamp a = new Timestamp(after.getTime());
            Timestamp b = new Timestamp(before.getTime());
            conn = dataSource.getConnection();
            ps = conn.prepareStatement("SELECT id FROM log WHERE time BETWEEN ? AND ? LIMIT ?, ?");
            ps.setTimestamp(1, a);
            ps.setTimestamp(2, b);
            ps.setInt(3, from);
            ps.setInt(4, count);
            Collection logs = new LinkedList();
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                logs.add(rs.getLong(1));
            }
            return logs;
        } catch (SQLException ex) {
            throw new EJBException("Error in Log.ejbFindAllAuthReg method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, ps);
        }
    }

    public Long getId() {
        return this.id;
    }

    public String getAction() {
        return this.action;
    }

    public Long getUserId() {
        return this.user_id;
    }

    public String getUserName() {
        return this.user_name;
    }

    public String getEntityType() {
        return this.entity_type;
    }

    public Date getTime() {
        Date d = new Date(time.getTime());
        return d;
    }

    public Long getEntityId() {
        return this.entity_id;
    }

    public String getEntityName() {
        return this.entity_name;
    }

    public String stringRepresentation() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getName());
        sb.append(": [");
        sb.append("id=");
        sb.append(this.id);
        sb.append(", action=");
        sb.append(this.action);
        sb.append(", user_id=");
        sb.append(this.user_id);
        sb.append(", user_name=");
        sb.append(this.user_name);
        sb.append(", entity_type=");
        sb.append(this.entity_type);
        sb.append(", entity_id=");
        sb.append(this.entity_id);
        sb.append(", entity_name=");
        sb.append(this.entity_name);
        sb.append("]");
        return sb.toString();
    }

    public int ejbHomeGetLogCount() {
        PreparedStatement selectIdCount = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            selectIdCount = conn.prepareStatement("SELECT COUNT(*) FROM log");
            ResultSet rs = selectIdCount.executeQuery();
            rs.next();
            return rs.getInt(1);
        } catch (Exception ex) {
            throw new EJBException("Error in Log.getLogCount method", ex);
        } finally {
            DatabaseUtil.closeConnection(conn, selectIdCount);
        }
    }
}
